package com.fs.base.service;

import java.io.Serializable;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import lombok.Data;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Service;

import com.fs.base.jpa.specification.Criteria;
import com.fs.base.utils.ApplicationUtils;
import com.fs.base.utils.PageHeper;

/**
 * 通用公共服务
 * @author TiddlerCJ
 */
@Service("baseService")
@Data
public class BaseService {
	private static final Logger log = Logger.getLogger(BaseService.class);
	@Autowired private ApplicationContext ctx;
	
	public <K> JpaRepository<K,Serializable> beanRepository(String className){
		JpaRepository<K,Serializable> T = null;
		try {
			className = beanNameFormat(className);
			T = getBean(className);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return T;
	}
	
	public <K> JpaRepository<K,Serializable> beanRepository(Class<?> class1){
		return beanRepository(class1.toString());
	}
	
	public <K> JpaSpecificationExecutor<K> beanSpecification(String className){
		JpaSpecificationExecutor<K> T = null;
		try {
			className = beanNameFormat(className);
			T = getBean(className);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return T;
	}
	public <K> JpaSpecificationExecutor<K> beanSpecification(Class<?> class1){
		return beanSpecification(class1.toString());
	}
	
	public <K> List<Object> findAllWithSort(String className,HttpServletRequest request,Criteria<Object> spec){
		List<Object> list = null;
		try {
			ApplicationUtils.addDataFilter(spec);
			
			Sort sort = PageHeper.sort(request);
			if(sort==null){
				list = beanSpecification(className).findAll(spec);
			}else{
				list = beanSpecification(className).findAll(spec, sort);
			}
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return list;
	}
	public <K> List<Object> findAll(String className,Criteria<Object> spec){
		List<Object> list = null;
		try {
			ApplicationUtils.addDataFilter(spec);
			
			list = beanSpecification(className).findAll(spec);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return list;
	}
	
	public Page<Object> page(String className,HttpServletRequest request,Criteria<Object> spec){
		Page<Object> page = null;
		try {
			ApplicationUtils.addDataFilter(spec);
			
			PageRequest pageable = PageHeper.pageRequest(request);
			page = beanSpecification(className).findAll(spec, pageable);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return page;
	}
	
	/**
	 * 取spring容器中的服务如：menuRepository,roleRepository...
	 * @param className
	 * @return
	 */
	private static String beanNameFormat(String className){
		if(className==null) return null;
		Integer lastIndex = className.lastIndexOf(".");
		className = className.substring(++lastIndex);
		//System.out.println("className:"+ className);
		//className = className.toLowerCase();
		className = className.substring(0, 1).toLowerCase().concat(className.substring(1)).concat("Repository");
		return className;
	}
	
	@SuppressWarnings("unchecked")
	public <Bean> Bean getBean(String beanName) {
		//System.out.println("beanName:"+ beanName);
		//System.out.println("beanName:"+ beanName.toLowerCase());
		return ctx != null ? (Bean)ctx.getBean(beanName) : null;
	}
	
}
